<script lang="ts" setup>
import { ref } from 'vue'

const inputText = ref('')
const outputText = ref('')
const errorMessage = ref('')
const isSuccess = ref(false)
const mode = ref<'encode' | 'decode'>('encode')

function encodeBase64() {
  try {
    if (!inputText.value.trim()) {
      errorMessage.value = '请输入要编码的文本'
      isSuccess.value = false
      return
    }
    
    outputText.value = btoa(unescape(encodeURIComponent(inputText.value)))
    errorMessage.value = '编码成功 ✓'
    isSuccess.value = true
  } catch (error) {
    errorMessage.value = `编码失败: ${(error as Error).message}`
    isSuccess.value = false
    outputText.value = ''
  }
}

function decodeBase64() {
  try {
    if (!inputText.value.trim()) {
      errorMessage.value = '请输入要解码的Base64文本'
      isSuccess.value = false
      return
    }
    
    outputText.value = decodeURIComponent(escape(atob(inputText.value)))
    errorMessage.value = '解码成功 ✓'
    isSuccess.value = true
  } catch (error) {
    errorMessage.value = `解码失败: ${(error as Error).message}`
    isSuccess.value = false
    outputText.value = ''
  }
}

function processText() {
  if (mode.value === 'encode') {
    encodeBase64()
  } else {
    decodeBase64()
  }
}

function switchMode() {
  mode.value = mode.value === 'encode' ? 'decode' : 'encode'
  // 交换输入输出内容
  const temp = inputText.value
  inputText.value = outputText.value
  outputText.value = temp
  errorMessage.value = ''
}

function clearAll() {
  inputText.value = ''
  outputText.value = ''
  errorMessage.value = ''
  isSuccess.value = false
}

function copyToClipboard() {
  if (outputText.value) {
    navigator.clipboard.writeText(outputText.value).then(() => {
      errorMessage.value = '已复制到剪贴板 ✓'
      isSuccess.value = true
    })
  }
}

function loadSample() {
  if (mode.value === 'encode') {
    inputText.value = 'Hello, 世界! 这是一个Base64编码示例。'
  } else {
    inputText.value = 'SGVsbG8sIOS4lueVjCEg6L+Z5piv5LiA5LiqQmFzZTY057yW56CB56S65L6L44CC'
  }
}

// 文件处理
const fileInput = ref<HTMLInputElement>()
const fileName = ref('')
const fileSize = ref('')

function handleFileSelect(event: Event) {
  const file = (event.target as HTMLInputElement).files?.[0]
  if (!file) return
  
  fileName.value = file.name
  fileSize.value = formatFileSize(file.size)
  
  const reader = new FileReader()
  reader.onload = (e) => {
    const result = e.target?.result as string
    if (mode.value === 'encode') {
      // 对于文件编码，直接使用base64
      const base64 = result.split(',')[1] // 移除data:xxx;base64,前缀
      outputText.value = base64
      errorMessage.value = `文件编码成功 ✓ (${fileName.value})`
      isSuccess.value = true
    }
  }
  
  if (mode.value === 'encode') {
    reader.readAsDataURL(file)
  }
}

function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

function selectFile() {
  fileInput.value?.click()
}

function downloadDecoded() {
  if (!outputText.value || mode.value !== 'decode') return
  
  try {
    // 尝试将base64转换为文件
    const byteCharacters = atob(outputText.value)
    const byteNumbers = new Array(byteCharacters.length)
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i)
    }
    const byteArray = new Uint8Array(byteNumbers)
    const blob = new Blob([byteArray])
    
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = fileName.value || 'decoded_file'
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    URL.revokeObjectURL(url)
    
    errorMessage.value = '文件下载成功 ✓'
    isSuccess.value = true
  } catch (error) {
    errorMessage.value = `下载失败: ${(error as Error).message}`
    isSuccess.value = false
  }
}
</script>

<template>
  <div class="base64-tool">
    <div class="mode-switch">
      <button 
        class="mode-btn" 
        :class="{ active: mode === 'encode' }"
        @click="mode = 'encode'"
      >
        🔒 编码
      </button>
      <button 
        class="mode-btn" 
        :class="{ active: mode === 'decode' }"
        @click="mode = 'decode'"
      >
        🔓 解码
      </button>
    </div>

    <div class="controls">
      <button class="btn btn-primary" @click="processText">
        {{ mode === 'encode' ? '编码' : '解码' }}
      </button>
      <button class="btn btn-secondary" @click="switchMode">🔄 切换模式</button>
      <button class="btn btn-success" @click="copyToClipboard" :disabled="!outputText">📋 复制结果</button>
      <button class="btn btn-warning" @click="loadSample">📝 加载示例</button>
      <button class="btn btn-danger" @click="clearAll">🗑️ 清空</button>
    </div>

    <div class="file-section" v-if="mode === 'encode'">
      <h3>文件编码</h3>
      <div class="file-controls">
        <button class="btn btn-info" @click="selectFile">📁 选择文件</button>
        <span v-if="fileName" class="file-info">
          {{ fileName }} ({{ fileSize }})
        </span>
      </div>
      <input 
        ref="fileInput" 
        type="file" 
        @change="handleFileSelect" 
        style="display: none"
      >
    </div>

    <div class="download-section" v-if="mode === 'decode' && outputText">
      <button class="btn btn-success" @click="downloadDecoded">💾 下载解码文件</button>
    </div>

    <div class="status" v-if="errorMessage" :class="{ 'error': !isSuccess, 'success': isSuccess }">
      {{ errorMessage }}
    </div>

    <div class="editor-container">
      <div class="editor-section">
        <h3>{{ mode === 'encode' ? '原始文本' : 'Base64文本' }}</h3>
        <textarea 
          v-model="inputText" 
          class="text-input"
          :placeholder="mode === 'encode' ? '请输入要编码的文本...' : '请输入要解码的Base64文本...'"
          spellcheck="false"
        ></textarea>
      </div>

      <div class="editor-section">
        <h3>{{ mode === 'encode' ? 'Base64结果' : '解码结果' }}</h3>
        <textarea 
          v-model="outputText" 
          class="text-output"
          :placeholder="mode === 'encode' ? 'Base64编码结果将显示在这里...' : '解码结果将显示在这里...'"
          readonly
          spellcheck="false"
        ></textarea>
      </div>
    </div>
  </div>
</template>

<style scoped>
.base64-tool {
  width: 100%;
}

.mode-switch {
  display: flex;
  gap: 0;
  margin-bottom: 20px;
  border-radius: 8px;
  overflow: hidden;
  width: fit-content;
}

.mode-btn {
  padding: 12px 24px;
  border: none;
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 16px;
  font-weight: 500;
}

.mode-btn.active {
  background: rgba(0, 123, 255, 0.8);
  color: #fff;
}

.mode-btn:hover:not(.active) {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}

.controls {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.2s ease;
  color: #fff;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  background: #007bff;
}

.btn-primary:hover:not(:disabled) {
  background: #0056b3;
}

.btn-secondary {
  background: #6c757d;
}

.btn-secondary:hover:not(:disabled) {
  background: #545b62;
}

.btn-info {
  background: #17a2b8;
}

.btn-info:hover:not(:disabled) {
  background: #117a8b;
}

.btn-success {
  background: #28a745;
}

.btn-success:hover:not(:disabled) {
  background: #1e7e34;
}

.btn-warning {
  background: #ffc107;
  color: #212529;
}

.btn-warning:hover:not(:disabled) {
  background: #e0a800;
}

.btn-danger {
  background: #dc3545;
}

.btn-danger:hover:not(:disabled) {
  background: #c82333;
}

.file-section, .download-section {
  margin-bottom: 20px;
  padding: 15px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.file-section h3 {
  margin: 0 0 10px 0;
  color: #fff;
  font-size: 1.1em;
}

.file-controls {
  display: flex;
  align-items: center;
  gap: 15px;
}

.file-info {
  color: #ccc;
  font-size: 14px;
}

.status {
  padding: 12px;
  border-radius: 6px;
  margin-bottom: 20px;
  font-weight: 500;
}

.status.error {
  background: rgba(220, 53, 69, 0.1);
  color: #dc3545;
  border: 1px solid rgba(220, 53, 69, 0.3);
}

.status.success {
  background: rgba(40, 167, 69, 0.1);
  color: #28a745;
  border: 1px solid rgba(40, 167, 69, 0.3);
}

.editor-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  height: 400px;
}

.editor-section {
  display: flex;
  flex-direction: column;
}

.editor-section h3 {
  margin: 0 0 10px 0;
  color: #fff;
  font-size: 1.1em;
}

textarea {
  flex: 1;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 6px;
  padding: 15px;
  color: #fff;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
  resize: none;
  outline: none;
}

textarea:focus {
  border-color: rgba(255, 255, 255, 0.4);
}

textarea::placeholder {
  color: rgba(255, 255, 255, 0.5);
}

.text-output {
  background: rgba(0, 0, 0, 0.4);
}

@media (max-width: 768px) {
  .editor-container {
    grid-template-columns: 1fr;
    height: auto;
  }
  
  .editor-section {
    height: 250px;
  }
  
  .controls {
    justify-content: center;
  }
  
  .file-controls {
    flex-direction: column;
    align-items: flex-start;
  }
}
</style>